﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;

namespace VidoopSecure
{
    public class CaptchaService : Service
    {
        /// <summary>
        /// Creates a <see cref="VidoopSecure.CaptchaService" /> object.
        /// </summary>
        /// <param name="manager">The <see cref="VidoopSecure.VSManager /> used
        /// to perform operations with this service.</param>
        /// <param name="site">The <see cref="VidoopSecure.Site" /> associated with
        /// this service.</param>
        /// <param name="apiBase">The base URL to be used for accessing services.</param>
        public CaptchaService(VSManager manager, Site site, string apiBase)
            : base(manager, site, apiBase)
        {
        }

        /// <summary>
        /// Create a new <see cref="VidoopSecure.Captcha" />.
        /// </summary>
        /// <param name="length">Number of categories that must be entered to solve the captcha.</param>
        /// <param name="orderMatters">Whether the categories should be entered in order.</param>
        /// <param name="width">Width of the captcha in images.</param>
        /// <param name="height">Height of the captcha in images.</param>
        /// <returns>A <see cref="VidoopSecure.Captcha" /> object.</returns>
        public Captcha NewCaptcha(int length, bool orderMatters, int width, int height) 
        {
            string apiUrl = this.CreateRequestUrl("/customers/" + this.Site.CustomerId + "/sites/" + this.Site.SiteName + "/services/captcha");

            string credentials = this.Site.Username + Util.CREDENTIALS_SEPARATOR + this.Site.Password;

            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("captcha_length", length.ToString());
            parameters.Add("order_matters", orderMatters.ToString());
            parameters.Add("width", width.ToString());
            parameters.Add("height", height.ToString());

            HttpProxy proxy = this.Manager.ApiCall(apiUrl, "POST", parameters, credentials);

            if (proxy.StatusCode != (int)HttpStatus.Created)
                throw new VidoopSecureException(proxy.StatusCode, "Failed to create a new Captcha.");
            else
            {
                Stream stream = proxy.Response.GetResponseStream();

                Captcha captcha = Captcha.FromXml(stream);
                proxy.Close();
                return captcha;
            }

        }


        /// <summary>
        /// Get an Captcha by ID.
        /// </summary>
        /// <param name="id">The identifier of the Captcha to be retrieved.</param>
        /// <returns>A <see cref="VidoopSecure.Captcha" /> object.</returns>
        /// <exception cref="VidoopSecure.VidoopSecureException">If the 
        /// VidoopSecure web service does not return a 201 HTTP status code,
        /// this exception will be thrown.
        /// </exception>
        /// <seealso cref="VidoopSecure" />       
        public Captcha GetCaptcha(string id) 
        {
            Captcha captcha = null;

            string apiUrl = this.CreateRequestUrl("/captchas/" + id);

            string credentials = this.Site.Username + Util.CREDENTIALS_SEPARATOR + this.Site.Password;
            
            HttpProxy proxy = this.Manager.ApiCall(apiUrl, "GET", null, credentials);
            if (proxy.StatusCode == (int)HttpStatusCode.OK)
            {
                captcha = Captcha.FromXml(proxy.Response.GetResponseStream());
                proxy.Close();
                return captcha;
            }
            else
            {
                proxy.Close();
                throw new VidoopSecureException(proxy.StatusCode, string.Format("Failed to retrieve Captcha whose ID is {0}", id));
            }
        }

        /// <summary>
        /// Verify the code for an Captcha.
        /// </summary>
        /// <param name="id">Captcha Id</param>
        /// <param name="code">Code to test the Captcha</param>
        /// <returns><typeparamref name="bool"/> indicating whether the code
        /// part of the solution to the Captcha.</returns>
        /// <seealso cref="VidoopSecure" />
        public bool VerifyCode(string id, string code) 
        {
            string apiUrl = this.CreateRequestUrl("/captchas/" + id);

            Dictionary<string,string> parameters = new Dictionary<string,string>
            {
                { "code", code }
            };
          
            string credentials = this.Site.Username + Util.CREDENTIALS_SEPARATOR + this.Site.Password;
            
            HttpProxy proxy = this.Manager.ApiCall(apiUrl, "POST", parameters, null);
            bool result = proxy.StatusCode == (int)HttpStatusCode.OK;
            proxy.Close();

            return result;
        }
    }
}
